import { ref, onMounted, onUnmounted, watch, isRef } from "vue";
import L, { type Map, type LatLngExpression, type LatLng } from "leaflet";
import "leaflet-routing-machine";
import "leaflet.polylineDecorator";

// 路线规划状态枚举
export type RoutePlanningState =
  | "idle"
  | "planning"
  | "planned"
  | "correcting"
  | "error";

// 路线类型枚举
export type RouteType = "driving" | "walking" | "cycling" | "transit";

// 路线点类型
export interface RoutePoint {
  /** 点ID */
  id: string | number;
  /** 纬度 */
  lat: number;
  /** 经度 */
  lng: number;
  /** 点名称 */
  name?: string;
  /** 点描述 */
  description?: string;
  /** 点类型 */
  type?: "start" | "end" | "waypoint";
  /** 自定义图标 */
  icon?: L.IconOptions;
}

// 路线选项
export interface RouteOptions {
  /** 路线类型 */
  routeType?: RouteType;
  /** 是否显示路线信息 */
  showRouteInfo?: boolean;
  /** 是否启用纠偏 */
  enableCorrection?: boolean;
  /** 路线样式 */
  polylineOptions?: L.PolylineOptions;
  /** 备选路线样式 */
  alternativePolylineOptions?: L.PolylineOptions;
  /** 路线箭头样式 */
  arrowOptions?: {
    repeat?: number;
    pixelSize?: number;
    headAngle?: number;
    color?: string;
  };
}

// 路线规划结果
export interface RouteResult {
  /** 路线ID */
  routeId: string;
  /** 路线点 */
  points: RoutePoint[];
  /** 路线坐标 */
  latlngs: LatLngExpression[];
  /** 路线距离(米) */
  distance: number;
  /** 预计时间(秒) */
  duration: number;
  /** 路线类型 */
  routeType: RouteType;
  /** 是否是备选路线 */
  isAlternative?: boolean;
}

// 路线规划回调函数
export interface RoutePlanningHooks {
  /** 路线规划开始前回调 */
  onBeforePlan?: () => void | Promise<void>;
  /** 路线规划成功后回调 */
  onPlanSuccess?: (result: RouteResult) => void | Promise<void>;
  /** 路线规划失败后回调 */
  onPlanError?: (error: Error) => void | Promise<void>;
  /** 路线纠偏完成后回调 */
  onRouteCorrected?: (
    correctedRoute: LatLngExpression[]
  ) => void | Promise<void>;
}

export function useRoutePlanning(
  map: Map | Ref<Map | null>,
  options: RouteOptions & RoutePlanningHooks = {}
) {
  // 状态管理 - 状态机实现
  const state = ref<RoutePlanningState>("idle");
  const currentRoute = ref<RouteResult | null>(null);
  const alternativeRoutes = ref<RouteResult[]>([]);
  const routeControl = ref<any>(null);
  const correctionService = ref<any>(null);
  const correctionProgress = ref(0);

  // 默认配置
  const defaultOptions: Required<Omit<RouteOptions, "arrowOptions">> = {
    routeType: "driving",
    showRouteInfo: true,
    enableCorrection: true,
    polylineOptions: {
      weight: 6,
      color: "#3388ff",
      opacity: 0.8
    },
    alternativePolylineOptions: {
      weight: 6,
      color: "#ff9900",
      opacity: 0.6,
      dashArray: "10, 10"
    }
  };

  // 默认箭头配置
  const defaultArrowOptions = {
    repeat: 50,
    pixelSize: 15,
    headAngle: 60,
    color: "#ffffff"
  };

  // 合并配置
  const mergedOptions = {
    ...defaultOptions,
    ...options,
    arrowOptions: { ...defaultArrowOptions, ...options.arrowOptions }
  };

  // 状态转换表
  const stateTransitions: Record<RoutePlanningState, RoutePlanningState[]> = {
    idle: ["planning", "error"],
    planning: ["planned", "idle", "error"],
    planned: ["correcting", "planning", "idle", "error"],
    correcting: ["planned", "error"],
    error: ["planning", "idle"]
  };

  // 状态转换方法
  const transitionState = async (
    newState: RoutePlanningState,
    error?: Error
  ) => {
    const currentState = state.value;

    // 检查状态转换是否合法
    if (!stateTransitions[currentState].includes(newState)) {
      const err = new Error(`不允许从 ${currentState} 转换到 ${newState}`);
      options.onPlanError?.(err);
      state.value = "error";
      return;
    }

    // 执行状态变更
    state.value = newState;

    // 错误状态处理
    if (newState === "error" && error) {
      options.onPlanError?.(error);
    }
  };

  // 初始化路线规划控件
  const initRouteControl = (mapInstance: Map) => {
    // 清除现有控件
    if (routeControl.value) {
      mapInstance.removeControl(routeControl.value);
    }

    // 创建路线规划控件
    routeControl.value = L.Routing.control({
      waypoints: [],
      routeWhileDragging: true,
      showAlternatives: true,
      draggableWaypoints: true,
      lineOptions: {
        styles: [
          mergedOptions.polylineOptions,
          mergedOptions.alternativePolylineOptions
        ]
      },
      // 根据路线类型设置不同的路由服务
      router:
        L.Routing[
          mergedOptions.routeType === "driving"
            ? "osrm"
            : mergedOptions.routeType === "walking"
              ? "foot"
              : mergedOptions.routeType === "cycling"
                ? "bike"
                : "transit"
        ]()
    }).addTo(mapInstance);

    // 监听路线计算完成事件
    routeControl.value.on("routesfound", handleRoutesFound);
    routeControl.value.on("routingerror", handleRoutingError);
  };

  // 处理路线计算完成
  const handleRoutesFound = async (e: any) => {
    const routes = e.routes;

    if (routes.length === 0) {
      transitionState("error", new Error("未找到路线"));
      return;
    }

    // 处理主路线
    const mainRoute = routes[0];
    const mainRouteResult = formatRouteResult(mainRoute, false);
    currentRoute.value = mainRouteResult;

    // 处理备选路线
    const alternatives = routes.slice(1);
    alternativeRoutes.value = alternatives.map((route: any, index: number) =>
      formatRouteResult(route, true, index)
    );

    // 应用路线纠偏
    if (mergedOptions.enableCorrection) {
      await applyRouteCorrection(mainRouteResult.latlngs);
    } else {
      // 添加路线箭头
      addRouteArrows(mainRouteResult.latlngs);
      // 触发成功回调
      options.onPlanSuccess?.(mainRouteResult);
      // 更新状态
      transitionState("planned");
    }
  };

  // 格式化路线结果
  const formatRouteResult = (
    route: any,
    isAlternative: boolean,
    index = 0
  ): RouteResult => {
    const points: RoutePoint[] = route.waypoints.map(
      (waypoint: any, i: number) => ({
        id: `waypoint-${i}`,
        lat: waypoint.latLng.lat,
        lng: waypoint.latLng.lng,
        type:
          i === 0
            ? "start"
            : i === route.waypoints.length - 1
              ? "end"
              : "waypoint",
        name:
          i === 0
            ? "起点"
            : i === route.waypoints.length - 1
              ? "终点"
              : `途经点${i}`
      })
    );

    return {
      routeId: isAlternative ? `alternative-${index}` : "main-route",
      points,
      latlngs: route.coordinates,
      distance: route.summary.totalDistance,
      duration: route.summary.totalTime,
      routeType: mergedOptions.routeType,
      isAlternative
    };
  };

  // 处理路线计算错误
  const handleRoutingError = (e: any) => {
    transitionState("error", new Error(e.error.message || "路线规划失败"));
  };

  // 应用路线纠偏
  const applyRouteCorrection = async (route: LatLngExpression[]) => {
    if (!route.length) return;

    transitionState("correcting");
    correctionProgress.value = 0;

    try {
      // 模拟路线纠偏过程
      const totalPoints = route.length;
      const correctedRoute: LatLngExpression[] = [];

      // 这里应该集成实际的路线纠偏服务
      // 简单模拟纠偏过程
      for (let i = 0; i < totalPoints; i++) {
        // 模拟处理延迟
        await new Promise(resolve => setTimeout(resolve, 50));

        // 模拟纠偏 - 在实际应用中这里会调用专业的纠偏API
        const originalPoint = route[i] as L.LatLng;
        // 添加微小随机偏移模拟纠偏效果
        const correctedPoint = L.latLng(
          originalPoint.lat + (Math.random() - 0.5) * 0.001,
          originalPoint.lng + (Math.random() - 0.5) * 0.001
        );

        correctedRoute.push(correctedPoint);
        correctionProgress.value = Math.round((i / totalPoints) * 100);
      }

      // 更新路线
      if (currentRoute.value) {
        currentRoute.value.latlngs = correctedRoute;
      }

      // 添加路线箭头
      addRouteArrows(correctedRoute);

      // 触发纠偏完成回调
      options.onRouteCorrected?.(correctedRoute);
      // 触发成功回调
      options.onPlanSuccess?.(currentRoute.value!);

      transitionState("planned");
      return correctedRoute;
    } catch (error) {
      transitionState("error", error as Error);
      return route;
    }
  };

  // 添加路线箭头
  const addRouteArrows = (latlngs: LatLngExpression[]) => {
    if (!map.value) return;

    // 使用polylineDecorator添加箭头
    L.polylineDecorator(L.polyline(latlngs), {
      patterns: [
        {
          repeat: mergedOptions.arrowOptions?.repeat || 50,
          symbol: L.Symbol.arrowHead({
            pixelSize: mergedOptions.arrowOptions?.pixelSize || 15,
            headAngle: mergedOptions.arrowOptions?.headAngle || 60,
            pathOptions: {
              color: mergedOptions.arrowOptions?.color || "#ffffff",
              weight: 2,
              opacity: 0.8
            }
          })
        }
      ]
    }).addTo(map.value);
  };

  // 规划路线
  const planRoute = async (
    start: LatLngExpression,
    end: LatLngExpression,
    waypoints?: LatLngExpression[]
  ) => {
    if (!map.value || state.value === "planning") return;

    try {
      // 触发规划前回调
      await options.onBeforePlan?.();

      // 更新状态为规划中
      transitionState("planning");

      // 确保路线控件已初始化
      if (!routeControl.value) {
        initRouteControl(map.value);
      }

      // 设置路线点
      const points = [start];
      if (waypoints && waypoints.length > 0) {
        points.push(...waypoints);
      }
      points.push(end);

      // 设置路线规划控件的途经点
      routeControl.value.setWaypoints(points);
    } catch (error) {
      transitionState("error", error as Error);
    }
  };

  // 添加途经点
  const addWaypoint = (point: LatLngExpression, index?: number) => {
    if (!routeControl.value) return;

    const waypoints = routeControl.value.getWaypoints();

    if (index !== undefined && index > 0 && index < waypoints.length) {
      waypoints.splice(index, 0, L.latLng(point));
    } else {
      // 默认添加到倒数第二个位置（终点前）
      waypoints.splice(waypoints.length - 1, 0, L.latLng(point));
    }

    routeControl.value.setWaypoints(waypoints);
  };

  // 移除途经点
  const removeWaypoint = (index: number) => {
    if (!routeControl.value) return;

    const waypoints = routeControl.value.getWaypoints();

    // 不能移除起点和终点
    if (index <= 0 || index >= waypoints.length - 1) return;

    waypoints.splice(index, 1);
    routeControl.value.setWaypoints(waypoints);
  };

  // 切换路线类型
  const setRouteType = (type: RouteType) => {
    mergedOptions.routeType = type;

    // 重新初始化路线控件以应用新的路线类型
    if (map.value) {
      initRouteControl(map.value);
    }
  };

  // 清除路线
  const clearRoute = () => {
    if (routeControl.value && map.value) {
      map.value.removeControl(routeControl.value);
      routeControl.value = null;
      currentRoute.value = null;
      alternativeRoutes.value = [];
      transitionState("idle");
    }
  };

  // 保存路线
  const saveRoute = (name: string): RouteResult | null => {
    if (!currentRoute.value) return null;

    // 这里可以将路线保存到本地存储或发送到服务器
    const savedRoute = { ...currentRoute.value, name };
    localStorage.setItem(
      `saved_route_${Date.now()}`,
      JSON.stringify(savedRoute)
    );

    return savedRoute;
  };

  // 加载路线
  const loadRoute = (routeId: string): RouteResult | null => {
    // 这里可以从本地存储或服务器加载路线
    const savedRoutes = Object.keys(localStorage).filter(key =>
      key.startsWith("saved_route_")
    );

    for (const key of savedRoutes) {
      const route = JSON.parse(localStorage.getItem(key) || "{}");
      if (route.routeId === routeId) {
        currentRoute.value = route;
        return route;
      }
    }

    return null;
  };

  // 初始化
  const init = () => {
    if (isRef(map) && !map.value) return;

    const mapInstance = isRef(map) ? map.value! : map;
    initRouteControl(mapInstance);
  };

  // 清理
  const destroy = () => {
    if (routeControl.value && map.value) {
      map.value.removeControl(routeControl.value);
    }

    if (correctionService.value) {
      // 清理纠偏服务
      correctionService.value = null;
    }
  };

  // 生命周期钩子
  onMounted(() => {
    if (!isRef(map) || map.value) {
      init();
    } else {
      // 如果map是ref且尚未初始化，等待其变化
      const unwatch = watch(map, newMap => {
        if (newMap) {
          init();
          unwatch();
        }
      });
    }
  });

  onUnmounted(() => {
    destroy();
  });

  return {
    // 状态数据
    state,
    currentRoute,
    alternativeRoutes,
    correctionProgress,

    // 控制方法
    planRoute,
    addWaypoint,
    removeWaypoint,
    setRouteType,
    clearRoute,
    saveRoute,
    loadRoute,
    applyRouteCorrection,

    // 初始化和销毁
    init,
    destroy
  };
}
